home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 4
/
FM Towns Free Software Collection 4 - Disc 1.iso
/
pao
/
towns
/
cdplay
/
src
/
sndplay.c
< prev
next >
Wrap
Text File
|
1991-10-18
|
6KB
|
187 lines
/* << High C V1.4 & 386ASM V2.0 >> ******************************************
**
** SND ファイルを再生します。
**
** 1991.03.19 : CREATE
** 1991.03.19 : FINISH
**
** < HISTORY >
** 1991.03.19 : CREATE
** 1991.03.25 : 音声を再生する時の音量を電子ボリュームの値と一緒にした.
**
** < note > : TABS = 4
**
** Programmed by Y.Hirata ( Nifty ID : NAB03321 )
**
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <snd.h>
#include <dos.h>
#include <msdos.cf>
#include "cdpn.h"
#include "sndplay.h"
/*-----------------------------------------------------------------------------
** SND BIOS の初期化および電子ボリュームの設定は、呼び側で行っておいて下さい.
-----------------------------------------------------------------------------*/
#define PCM_MAXCH 8 /* PCM チャンネル数 */
static int Sndsize[PCM_MAXCH] ; /* PCM 音声データサイズ */
static char *Snddata[PCM_MAXCH] ; /* PCM 音声格納領域 */
struct _SNDPLAY_DATA {
char name[8] ; /* サウンドネーム */
ulong sid ; /* サウンドID */
ulong len ; /* データ幅 */
ulong loop_p ; /* ループポイント */
ulong loop_len ; /* ループレングス */
ushort sf ; /* サンプリング周波数 */
short hosei ; /* 原音の補正(ピッチベンド) */
uchar onkai ; /* 原音の音階 */
uchar flg ; /* ?フラグ */
} ;
union _SNDPLAY_CHECK {
struct _SNDPLAY_DATA data ;
char buf[30] ;
} SNDPLAY_check[PCM_MAXCH] ;
static char SNDPLAY_loadflg[PCM_MAXCH] = { FALSE, FALSE, FALSE, FALSE ,
FALSE, FALSE, FALSE, FALSE } ;
/************************* DTAの設定 ************************************/
void SNDPLAY_setdta( SNDPLAY_DTA *p )
{
Registers.AX.LH.H = 0x1a ;
Registers.DX.R = (uint)p ;
Registers.DS.R = getds() ;
calldos() ;
}
/******************* 最初に一致するファイル名の検索 ************************/
int SNDPLAY_firstsearch( char *path,int attr,SNDPLAY_DTA *dta )
/*=============================================================================
** 最初に一致するファイル名の検索を行う.
**
** < INPUT > : path 検索パス
** : attr 検索ファイル属性
** < OUTPUT > : dta DTA格納領域
** < RETURN > : ファイルが検索できたら 真値 , みつからなければ 偽値
=============================================================================*/
{
SNDPLAY_setdta( dta ) ;
Registers.AX.LH.H = 0x4e ;
Registers.CX.R = attr ; /* ファイルの種類 */
Registers.DX.R = (uint)path ; /* ファイル名 */
Registers.DS.R = getds() ;
calldos();
if ( (Registers.Flags & 0x0001) != 0 )
return ( FALSE ) ;
else
return ( TRUE ) ; /* 成功ならば 真 でreturn */
}
/*************************** ファイルサイズ取得 ****************************/
int SNDPLAY_getfsize( int ch,char *fname )
/*=============================================================================
** ファイルサイズの取得を行う.
**
** < INPUT > : fname ファイル名
** : ch チャンネル ( 71 ~ 64 )
** < OUTPUT > : なし
** < RETURN > : ファイルサイズ( ファイルが見つからない場合には、-1 )
=============================================================================*/
{
SNDPLAY_DTA dta ;
ushort attr=0 ;
if ( SNDPLAY_firstsearch( fname,attr,&dta ) ) { /* 最初のエントリ */
Sndsize[71-ch] = dta._fsize ;
return( dta._fsize ) ;
} else { /* ファイルが見つからない */
return( -1 ) ;
}
}
/*************************** SND DATA の読込み *****************************/
int SNDPLAY_load( int ch,char *fname )
/*=============================================================================
** SNDファイルを読み込む.
**
** < INPUT > : fname ファイル名
** : ch チャンネル ( 71 ~ 64 )
** < OUTPUT > : なし
** < RETURN > : ファイルが読み込めたら 真値 , 読み込めなければ 偽値
=============================================================================*/
{
FILE *fp;
if ( SNDPLAY_getfsize( ch,fname ) == -1 ) return( FALSE ) ;
if ( SNDPLAY_loadflg[71-ch] ) {
SNDPLAY_loadflg[71-ch] = FALSE ;
free( Snddata[71-ch] ) ;
}
Snddata[71-ch] = malloc( Sndsize[71-ch] ) ; /* SND データ格納領域確保 */
if ( Snddata[71-ch] == NULL ) {
return( FALSE ) ;
} else {
SNDPLAY_loadflg[71-ch] = TRUE ;
fp = fopen( fname,"rb" ) ;
fread( Snddata[71-ch],1,Sndsize[71-ch],fp ) ;
fclose( fp ) ;
}
memcpy( SNDPLAY_check[71-ch].buf,Snddata[71-ch],30 ) ;
return( TRUE ) ;
}
/***************************** SND DATA の再生 *****************************/
int SNDPLAY_play( int ch,char *fname )
/*=============================================================================
** SNDファイルを再生する.
**
** < INPUT > : fname ファイル名
** : ch チャンネル ( 71 ~ 64 )
** < OUTPUT > : なし
** < RETURN > : 再生できたら 真値 , 再生できなければ 偽値
=============================================================================*/
{
int vol ;
if ( !SNDPLAY_load( ch,fname ) ) return( FALSE ) ;
SND_pcm_play_stop( ch ) ;
if ( Flg.mute ) { /* ミュート中 */
vol = ZERO ; /* 最小値とする */
} else {
vol = Evol ; /* 電子ボリューム値と同じにする */
}
SND_pcm_play( ch,SNDPLAY_check[71-ch].data.onkai,vol,Snddata[71-ch] ) ;
return( TRUE ) ;
}
/***************************** SND DATA の停止 *****************************/
void SNDPLAY_stop( int ch )
/*=============================================================================
** SNDファイルの再生を停止する.
**
** < INPUT > : チャンネル ( 71 ~ 64 )
** < OUTPUT > : なし
** < RETURN > : なし
=============================================================================*/
{
if ( SNDPLAY_loadflg[71-ch] ) {
SND_pcm_play_stop( ch ) ;
SNDPLAY_loadflg[71-ch] = FALSE ;
free( Snddata[71-ch] ) ;
}
}